<template>
  <div class="big-box" :style="{width: queenWidth + 'px', height: queenHeight + 'px'}">
    <canvas
      id="canvas"
      ref="canvas"
      class="canvas-main"
      @mousedown="canvasDown($event)"
      @mouseup="canvasUp($event)"
      @mousemove="canvasMove($event)"
      @touchstart="canvasDown($event)"
      @touchend="canvasUp($event)"
      @touchmove="canvasMove($event)"
    >
    </canvas>
    <div id="control" class="canvas-control">
      <div id="canvas-color">
        <h5>
          画笔颜色</h5>
        <ul>
          <li
            v-for="item in colors"
            :key="item.lineColor"
            :class="{'active':config.lineColor === item}"
            :style="{ background: item }"
            @click="setColor(item)"
          ></li>
        </ul>
      </div>
      <div id="canvas-brush">
        <h5>画笔大小</h5>
        <i
          v-for="pen in brushs"
          :key="pen.lineWidth"
          :class="['iconfont',pen.className,{'active': config.lineWidth === pen.lineWidth}]"
          @click="setBrush(pen.lineWidth)"
        ></i>
      </div>
      <div id="canvas-control">
        <h5>操作</h5>
        <i
          v-for="control in controls"
          :key="control.title"
          :title="control.title"
          :class="control.className"
          @click="controlCanvas(control.action)"
        ></i>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      timerWidth: false,
      timerHeight: false,
      queenWidth: document.documentElement.clientWidth,
      queenHeight: document.documentElement.clientHeight,
      url: '',
      colors: ['#fef4ac', '#0018ba', '#ffc100', '#f32f15', '#cccccc', '#5ab639'],
      brushs: [{
        className: 'small icon-huabi',
        lineWidth: 3
      }, {
        className: 'middle icon-huabi',
        lineWidth: 6
      }, {
        className: 'big icon-huabi',
        lineWidth: 12
      }],
      context: {},
      imgUrl: [],
      canvasMoveUse: false,
      // 存储当前表面状态数组-上一步
      preDrawAry: [],
      // 存储当前表面状态数组-下一步
      nextDrawAry: [],
      // 中间数组
      middleAry: [],
      // 配置参数
      config: {
        lineWidth: 1,
        lineColor: '#f2849e',
        shadowBlur: 2
      }
    }
  },
  created () {
  },
  mounted () {
    window.onresize = () => {
      return (() => {
        this.queenWidth = document.documentElement.clientWidth
        this.queenHeight = document.documentElement.clientHeight
      })()
    }
    let canvas = document.querySelector('#canvas')
    this.context = canvas.getContext('2d')
    this.initDraw()
    this.setCanvasStyle()
  },
  destroyed () {
  },
  watch: {
    queenWidth (val) {
      if (!this.timerWidth) {
        // 一旦监听到的screenWidth值改变，就将其重新赋给data里的screenWidth
        this.queenWidth = val
        this.timerWidth = true
        let that = this
        setTimeout(function () {
          that.timerWidth = false
        }, 400)
      }
    },
    queenHeight (val) {
      if (!this.timerHeight) {
        // 一旦监听到的screenWidth值改变，就将其重新赋给data里的screenWidth
        this.queenHeight = val
        this.timerHeight = true
        let that = this
        setTimeout(function () {
          that.timerHeight = false
        }, 400)
      }
    }
  },
  computed: {
    controls () {
      return [{
        title: '上一步',
        action: 'prev',
        className: this.preDrawAry.length ? 'active iconfont icon-iconset0446' : 'iconfont icon-iconset0446'
      }, {
        title: '下一步',
        action: 'next',
        className: this.nextDrawAry.length ? 'active iconfont icon-iconset0447' : 'iconfont icon-iconset0447'
      }, {
        title: '清除',
        action: 'clear',
        className: (this.preDrawAry.length || this.nextDrawAry.length) ? 'active iconfont icon-shanchu' : 'iconfont icon-shanchu'
      }]
    }
  },
  methods: {
    removeImg (src) {
      this.imgUrl = this.imgUrl.filter(item => item !== src)
    },
    initDraw () {
      const preData = this.context.getImageData(0, 0, this.queenWidth, this.queenHeight)
      // 空绘图表面进栈
      this.middleAry.push(preData)
    },
    canvasMove (e) {
      if (this.canvasMoveUse) {
        console.log('canvasMove')
        const t = e.target
        let canvasX // e.target.parentNode
        let canvasY
        canvasX = e.clientX - t.parentNode.offsetLeft
        canvasY = e.clientY - (t.parentNode.offsetTop)
        console.log(canvasX, canvasY)
        this.context.lineTo(canvasX, canvasY)
        this.context.stroke()
      }
    },
    beginPath (e) {
      const canvas = document.querySelector('#canvas')
      if (e.target !== canvas) {
        console.log('beginPath')
        this.context.beginPath()
      }
    },
    // mouseup
    canvasUp (e) {
      console.log('canvasUp')
      const preData = this.context.getImageData(0, 0, this.queenWidth, this.queenHeight)
      if (!this.nextDrawAry.length) {
        // 当前绘图表面进栈
        this.middleAry.push(preData)
      } else {
        this.middleAry = []
        this.middleAry = this.middleAry.concat(this.preDrawAry)
        this.middleAry.push(preData)
        this.nextDrawAry = []
      }
      this.canvasMoveUse = false
    },
    // mousedown
    canvasDown (e) {
      this.canvasMoveUse = true
      // client是基于整个页面的坐标
      // offset是cavas距离顶部以及左边的距离
      const canvasX = e.clientX - e.target.parentNode.offsetLeft
      const canvasY = e.clientY - (e.target.parentNode.offsetTop)
      this.setCanvasStyle()
      // 清除子路径
      this.context.beginPath()
      this.context.moveTo(canvasX, canvasY)
      console.log('moveTo', canvasX, canvasY)
      // 当前绘图表面状态
      const preData = this.context.getImageData(0, 0, this.queenWidth, this.queenHeight)
      // 当前绘图表面进栈
      this.preDrawAry.push(preData)
    },
    // 设置颜色
    setColor (color) {
      this.config.lineColor = color
    },
    // 设置笔刷大小
    setBrush (type) {
      this.config.lineWidth = type
    },
    // 操作
    controlCanvas (action) {
      switch (action) {
        case 'prev':
          if (this.preDrawAry.length) {
            const popData = this.preDrawAry.pop()
            const midData = this.middleAry[this.preDrawAry.length + 1]
            this.nextDrawAry.push(midData)
            this.context.putImageData(popData, 0, 0)
          }
          break
        case 'next':
          if (this.nextDrawAry.length) {
            const popData = this.nextDrawAry.pop()
            const midData = this.middleAry[this.middleAry.length - this.nextDrawAry.length - 2]
            this.preDrawAry.push(midData)
            this.context.putImageData(popData, 0, 0)
          }
          break
        case 'clear':
          this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height)
          this.preDrawAry = []
          this.nextDrawAry = []
          this.middleAry = [this.middleAry[0]]
          break
      }
    },
    // 生成图片
    getImage () {
      const canvas = document.querySelector('#canvas')
      const src = canvas.toDataURL('image/png')
      this.imgUrl.push(src)
    },
    // 设置绘画配置
    setCanvasStyle () {
      this.context.lineWidth = this.config.lineWidth
      this.context.shadowBlur = this.config.shadowBlur
      this.context.shadowColor = this.config.lineColor
      this.context.strokeStyle = this.config.lineColor
    }
  }
}
</script>
<style>
  .big-box{
    display: flex;
    align-items: center;
    position: relative;
    font-size: 12px;
    border: 1px solid deeppink;
  }
  .canvas-main{
    width: 100%;
    height: 100%;
    position:absolute;
    left: 0;
    top: 0;
  }
  .draw h5 {
    margin-bottom: 10px;
  }
  .canvas-control{
    z-index: 2;
    border: 1px solid gray;
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
  }
  #canvas{
    cursor: crosshair;
  }
  #control{
    width: 130px;
    height: 400px;
    margin-left: 4px;
  }
  #control div{
    padding: 5px;
  }
  #canvas-color ul{
    overflow: hidden;
    margin: 0;
    padding: 0;
  }
  #canvas-color ul li{
    float: left;
    display: inherit;
    width: 13px;
    height: 13px;
    border: 3px #fff solid;
    margin: 8px;
    cursor: pointer;
  }
  #canvas-color .active {
    border: 1px solid #f2849e;
  }
  #canvas-brush i{
    display: inline-block;
    width: 20px;
    height: 15px;
    margin-left: 10px;
    cursor: pointer;
  }
  #canvas-brush .small {
    font-size: 12px;
  }
  #canvas-brush .middle {
    font-size: 14px;
  }
  #canvas-brush .big {
    font-size: 16px;
  }
  #canvas-control i{
    display: inline-block;
    font-size: 14px;
    width: 20px;
    height: 15px;
    margin-left: 10px;
    cursor: pointer;
  }
  #canvas-control .active,
  #canvas-brush .active {
    color: #f2849e;
  }
</style>
